package com.grm.security.login;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.grm.sys.service.mapper.SysRoleMapper;
import com.grm.sys.service.mapper.SysUserMapper;
import com.grm.sys.service.mapper.SysUserRoleMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;


/**
 * 登录参数为json格式时，security无法获取，需要重写下
 * <p>
 * 单体不分离项目不需要，直接form表单提交获取登录参数即可
 *
 * @author gaorimao
 * @date 2022/02/08
 */
@Slf4j
public class LoginParamFilter extends UsernamePasswordAuthenticationFilter {
    private static final String POST = "POST";

    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;
    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Value("${password.secret}")
    private String secret;

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        if (POST.equalsIgnoreCase(request.getMethod())) {
            ObjectMapper mapper = new ObjectMapper();
            InputStream inputStream;
            Map<String, String> authenticationBean;
            try {
                inputStream = request.getInputStream();
                authenticationBean = mapper.readValue(inputStream, Map.class);
            } catch (IOException e) {
                throw new AuthenticationServiceException("Authentication method io exception: " + request.getMethod());
            }
            String username = authenticationBean.get("username");
            String password = authenticationBean.get("password");
            BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
            String encodePassword = encoder.encode(password + secret);
            log.info("password={},encodePassword={}",password,encodePassword);
            UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
            this.setDetails(request, authRequest);
            return this.getAuthenticationManager().authenticate(authRequest);

        }
        // 只能是post请求
        throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
    }

}